import java.util.Comparator;
import java.util.ArrayList;
import java.util.HashMap;


public class StringList{
	ArrayList<StringListElement> vals;

	
	public static void main(String[] args){
		StringList sl = new StringList();
		sl.add(new StringListElement("abc", "file1", 3,4,5));
		sl.add(new StringListElement("def", "file2", 4,5,6));
		sl.add(new StringListElement("def", "file2", 4,5,7));
		sl.add(new StringListElement("def", "file3", 4,5,6));
		sl.add(new StringListElement("ghi", "file1", 3,4,5));
		System.out.println("sl: " + sl);
		StringList sl2 = new StringList();
		sl2.add(new StringListElement("abc", "file1", 3,4,5));
		sl2.add(new StringListElement("abc", "file2", 3,4,5));
		sl2.add(new StringListElement("def", "file2", 4,5,8));
		sl2.add(new StringListElement("asdf", "file1", 3,4,5));
		System.out.println("sl2: " + sl2);
		System.out.println("sl inters sl2: " + inters(sl, sl2));
		System.out.println("sl union sl2: " + union(sl, sl2));
		System.out.println("sl diff sl2: " + diff(sl, sl2));
	}
	
	public static int pound(StringList sl){
		int size = 0;
		for (int i = 0; i < sl.vals.size(); i++){
			size += sl.vals.get(i).info.size();
		}
		System.out.println("i think size is " + sl.vals.size() + " " + sl.vals);
		return sl.vals.size();
	}
	
	public String toString(){
		String ret = "{";
		for (int i = 0; i < vals.size(); i++){
			ret += vals.get(i).toString();
			if (i != vals.size()-1){
				ret += ", ";
			}
		}
		return ret + "}";
	}


	public StringList(){
		vals = new ArrayList<StringListElement>();
	}

	public static StringList inters(StringList sl1, StringList sl2){

		StringList ret = new StringList();
		StringListElement curele;
		HashMap<String, StringListElement> table = new HashMap<String, StringListElement>();
		for (int i = 0; i < sl1.vals.size(); i++){//this is everything present in sl1
			table.put(sl1.vals.get(i).value, sl1.vals.get(i));
		}
		for (int i = 0; i < sl2.vals.size(); i++){//for every element in sl2, check if it's in sl1, and if so union the metadata and add it to ret
			if (table.containsKey(sl2.vals.get(i).value)){
				curele = table.get(sl2.vals.get(i).value);
				/*for (int j = 0; j < curele.info.size(); j++){
					
				}*/

				curele.addInfo(sl2.vals.get(i).info);
				ret.add(curele);
			}
		}


		return ret;
	}
	
	public static StringList union(StringList sl1, StringList sl2){
		StringList ret = new StringList();
		StringListElement curele;
		HashMap<String, StringListElement> table = new HashMap<String, StringListElement>();
		for (int i = 0; i < sl1.vals.size(); i++){
			curele = sl1.vals.get(i);
			table.put(curele.value, curele);
			ret.add(curele);
		}
		for (int i = 0; i < sl2.vals.size(); i++){
			curele = table.get(sl2.vals.get(i).value);
			if (table.containsKey(curele)){
				curele.addInfo(sl2.vals.get(i).info);
				ret.add(curele);
			}
			else{
				ret.add(sl2.vals.get(i));
			}
		}
		return ret;
	}
	
	public static StringList diff(StringList sl1, StringList sl2){
		StringList ret = new StringList();
		StringListElement curele;
		HashMap<String, StringListElement> table = new HashMap<String, StringListElement>();
		for (int i = 0; i < sl2.vals.size(); i++){//table contains all of the elements we can't keep
			curele = sl2.vals.get(i);
			table.put(curele.value, curele);
		}
		for (int i = 0; i < sl1.vals.size(); i++){
			curele = sl1.vals.get(i);
			if (!table.containsKey(curele.value)){
				ret.add(curele);
			}
		}
		return ret;
	}



	public void add(StringListElement sle){
		String newval = sle.value;
		if (newval == null) return;
		boolean found = false;
		for (int i = 0; i < vals.size(); i++){
			if (newval.equals(vals.get(i).value)){
				found = true;
				vals.get(i).addInfo(sle.info);
			}
		}
		if (!found){
			vals.add(sle);
		}
	}


	private class StringListComparator<StringList> implements Comparator<StringList>{

		@Override
		public int compare(StringList sl1, StringList sl2) {
			// TODO Auto-generated method stub
			return 0;
		}

	}

}
